package com.bkhc.product.service;

import com.bkhc.common.enu.ProductStatusEnum;
import com.bkhc.common.permissions.bean.RoleDetail;
import com.bkhc.common.permissions.bean.UserPermission;
import com.bkhc.common.service.UserService;
import com.bkhc.common.util.CommonUtil;
import com.bkhc.common.util.response.PageUtil;
import com.bkhc.common.util.response.ResultCode;
import com.bkhc.common.util.response.ResultJson;
import com.bkhc.common.vo.UserBean;
import com.bkhc.product.entity.*;
import com.bkhc.product.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.stream.Collectors;

import static jdk.nashorn.internal.objects.Global.print;

@Service
public class ProductService {

    @Autowired
    private ProductRepository repository;

    @Autowired
    private SpecRepository SpecRepository;

    @Autowired
    private GoodspecRepository goodspecRepository;

    @Autowired
    private GoodsRepository instanceRepository;

    @Autowired
    private BrandRepository brandRepository;
    @Autowired
    private BrandProductRepository brandProductRepository;
    @Autowired
    private GoodsRepository goodsRepository;
    @Autowired
    private SpecRangeRepository specRangeRepository;
    @Autowired
    private BrandGoodsRepository brandGoodsRepository;
    @Autowired
    private BrandGoodPriceRepository brandGoodPriceRepository;

    @Autowired
    private ProductFileRepository productFileRepository;

    @Autowired
    private ProductVideoRepository productVideoRepository;

    @Autowired
    private UserService userService;

    @Value("${spring.application.name}")
    private String appName;

    public ResultJson<?> findProduct(Product product, int pageIndex, int pageSize){
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        Page<Product> page = null;
        if(product == null){
            product = new Product();
        }

        page = repository.findAll(product, pageRequest);
        List<Product> products = page.getContent();
        if(!CollectionUtils.isEmpty(products)){
            for(Product prod:products){
                prod.setProductSpecList(SpecRepository.findByProductCode(prod.getProductCode()));;
            }
        }
        PageUtil pageUtil = new PageUtil(page);
        ResultJson<PageUtil> resultJson = ResultJson.success();
        resultJson.setData(pageUtil);
        return resultJson;
    }

    public ResultJson<?> findProductByUserId(int pageIndex, int pageSize) {
        UserBean userBean = CommonUtil.getCrruentUser();
        if (userBean == null){ return ResultJson.success();}
        UserPermission userPermission = userService.queryUserPermission(userBean.getUserId());
        Sort.Order orders = new Sort.Order(Sort.Direction.DESC, "updateDate");
        PageRequest pageRequest = PageRequest.of(pageIndex-1, pageSize, Sort.by(orders));
        boolean isAdmin = userPermission.getRoles().stream().anyMatch(roleDetail -> "admin".equals(roleDetail.getRole_code()));
        Product product = new Product();
        if (!isAdmin) {
            String userId = userBean.getUserId();
            product.setPartnerId(userId);
        }
        Page<Product> page = repository.findAll(product, pageRequest);
        List<Product> products = page.getContent();
        List<String> productCodes = new ArrayList<>();
        if(!CollectionUtils.isEmpty(products)){
            for(Product prod:products){
                productCodes.add(prod.getProductCode());
            }
            List<Spec> specs = SpecRepository.findInProductCode(productCodes);
            List<String> specCodes = new ArrayList<>();
            if(!CollectionUtils.isEmpty(specs)){
                specCodes = specs.stream().map(Spec::getSpecCode).collect(Collectors.toList());
                List<SpecRange> ranges = specRangeRepository.findInSpecCodeList(specCodes);
                for(Spec spec:specs){
                    spec.setRanges(ranges.stream().filter(x->x.getSpecCode().equals(spec.getSpecCode())).collect(Collectors.toList()));
                }
                for(Product product1:products){
                    product1.setProductSpecList(specs.stream().filter(y->y.getProductCode().equals(product1.getProductCode())).collect(Collectors.toList()));
                }
            }
        }
        PageUtil pageUtil = new PageUtil(page);
        ResultJson<PageUtil> resultJson = ResultJson.success();
        resultJson.setData(pageUtil);
        return resultJson;
    }

    public ResultJson<?> updateProduct(Product product) {
        if(StringUtils.isEmpty(product.getProductCode())){
            repository.save(product);
        }else{
        Product o = repository.findByProductCode(product.getProductCode());
        if(o==null){
            ResultJson<Page<Product>> resultJson = ResultJson.failure(ResultCode.NOT_FOUND);
            return resultJson;
        }
            repository.save(product);
        // 设计缺陷，同时需要更新brand Product表
            brandProductRepository.updateProductName(product.getProductName(),product.getProductCode());
        }
        List<Spec> productSpecList = product.getProductSpecList();
        List<Spec> oldsepc = SpecRepository.findByProductCode(product.getProductCode());
        if(!CollectionUtils.isEmpty(oldsepc)){
            List<String> specCodeList = oldsepc.stream().map(Spec::getSpecCode).collect(Collectors.toList());
            specRangeRepository.deleteBySpecCodeIn(specCodeList);
            for(String specCode:specCodeList){
                List<Spec> needDelete = productSpecList.stream().filter(x ->specCode .equals(x.getSpecCode())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(needDelete)){
                    SpecRepository.deleteBySpecCode(specCode);
                }
            }
        }

        if(!CollectionUtils.isEmpty(productSpecList)){
        // 存在新增属性
            List<Spec> newproductSpecList = productSpecList.stream().filter(x -> StringUtils.isEmpty(x.getSpecCode())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(newproductSpecList)||oldsepc.size()>productSpecList.size()){
                //删掉商品
                goodspecRepository.deleteByProductCode(product.getProductCode());
                goodsRepository.deleteByProductCode(product.getProductCode());

                //删掉品牌商品
                brandProductRepository.deleteByProductCode(product.getProductCode());
                brandGoodsRepository.deleteByProductCode(product.getProductCode());
                brandGoodPriceRepository.deleteByProductCode(product.getProductCode());
            }
            for(Spec s:productSpecList){
                s.setProductCode(product.getProductCode());
                SpecRepository.save(s);
                if(!CollectionUtils.isEmpty(s.getRanges())){
                    for(SpecRange rang:s.getRanges()){
                        rang.setSpecCode(s.getSpecCode());
                        specRangeRepository.save(rang);
                    }
                }
            }
        }



        return ResultJson.success();
    }

    public ResultJson<?> updatePartnerId(Integer id, String partnerId) {
        Product product = repository.findById(id);
        product.setPartnerId(partnerId);
        return ResultJson.ok(repository.save(product));
    }

    public boolean isModifySpec(List<Spec> oldSpec,List<Spec> newSpec){
        if(oldSpec.size()!=newSpec.size()){
            return true;
        }
        boolean isModify = false;
        for(Spec ps:newSpec){
            Spec tem = null;
            for(Spec oldps:oldSpec){
                if(oldps.getSpecCode().equals(ps.getSpecCode())){
                    tem = oldps;
                }
            }
            if(tem == null){
                isModify = true;
                break;
            }
        }
        return isModify;
    }


    public ResultJson<?> deleteProduct(String productCode) {
        UserPermission userPermission = CommonUtil.getCrruentUserPermission(appName);
        boolean isAdmin = userPermission.getRoles().stream().anyMatch(roleDetail -> "admin".equals(roleDetail.getRole_code()));
        if(!isAdmin){
            return null;
        }
        // 删掉产品信息
        repository.deleteByProductCode(productCode);
        // 删掉产品规格信息
        specRangeRepository.deleteByProductCode(productCode);
        SpecRepository.deleteByProductCode(productCode);

        //删掉商品
        goodspecRepository.deleteByProductCode(productCode);
        goodsRepository.deleteByProductCode(productCode);

        //删掉品牌商品
        brandProductRepository.deleteByProductCode(productCode);
        brandGoodsRepository.deleteByProductCode(productCode);
        brandGoodPriceRepository.deleteByProductCode(productCode);

        return ResultJson.success();
    }

    public ResultJson<List<Product>> findAllProducts() {
        List<Product> products = repository.findAllByStatus(ProductStatusEnum.Available);
        ResultJson<List<Product>> resultJson = ResultJson.success();
        resultJson.setData(products);
        return  resultJson;
    }


//    public ResultJson<?> addProduct(Product product) {
//        Product o = repository.findByProductName(product.getProductName());
//        if(o!=null){
//            ResultJson<Page<Product>> resultJson = ResultJson.failure(ResultCode.ISEXIT_RESURCE);
//            return resultJson;
//        }
//        product.setStatus(ProductStatusEnum.Available);
//        repository.save(product);
//        List<ProductSpec> productspecs = product.getProductSpecList();
//        if(!CollectionUtils.isEmpty(productspecs)){
//            for(ProductSpec spec:productspecs){
//                spec.setProductCode(product.getProductCode());
//            }
//            SpecRepository.saveAll(productspecs);
//        }
//
//        ResultJson<List<Product>> resultJson = ResultJson.success();
//        return resultJson;
//    }

    /**
     *
     * @param
     * @return
     * 添加产品
     */

    public ResultJson<?> addProduct(Product product){
        Product p = repository.findByProductName(product.getProductName());

        if (product != null){
            ResultJson<Page<Product>> resultJson = ResultJson.failure(ResultCode.ISEXIT_RESURCE);
                return resultJson;
        }
        product.setStatus(ProductStatusEnum.Available);
        repository.save(product);
    //用商品属性接收前端发送来的数据
        List<Spec> list = product.getProductSpecList();
    //创建一个商品属性实例 保存信息
        Spec s = new Spec();
        if (list != null){
            for (Spec a: list) {
                        s.setSpecName(a.getSpecName());
                         s.setSpecCode(a.getSpecCode());
            }
            SpecRepository.saveAll(list);

        }
        ResultJson<List<Product>> resultJson = ResultJson.success();
        return resultJson;
    }





    public ResultJson<?> findProductDetail(String productCode) {
        Product product = repository.findByProductCode(productCode);
        List<Spec> productspec = SpecRepository.findByProductCode(productCode);
        if(!CollectionUtils.isEmpty(productspec)){
            for(Spec spec:productspec){
                spec.setRanges(specRangeRepository.findBySpecCode(spec.getSpecCode()));
            }
        }
        List<Brand> brands = brandRepository.getBrandByProduct(productCode);
        product.setProductSpecList(productspec);
        product.setBrandList(brands);
        ResultJson<Product> resultJson = ResultJson.success();
        resultJson.setData(product);
        return resultJson;
    }

    public Product getProductDetailByProductCode(String productCode){
        Product product = repository.findByProductCode(productCode);
        List<Spec> productspec = SpecRepository.findByProductCode(productCode);
        List<Brand> brands = brandRepository.getBrandByProduct(productCode);
        product.setProductSpecList(productspec);
        product.setBrandList(brands);
        return product;
    }

    public ResultJson<?> getProductSpec(String productCode) {
        List<Spec> productSpecs = SpecRepository.findByProductCode(productCode);
        ResultJson<List<Spec> > resultJson = ResultJson.success();
        resultJson.setData(productSpecs);
        return resultJson;
    }

    public ResultJson<List<Spec>> querySpecByProductCode(String productCode) {
        List<Spec> productspecs = SpecRepository.findByProductCode(productCode);
        ResultJson<List<Spec>> resultJson = ResultJson.success();
        resultJson.setData(productspecs);
        return  resultJson;
    }

    public ResultJson<?> addOrUpdateProductSchema(Product product) {
        Product entity = repository.findByProductName(product.getProductName());
        if(entity == null){
            product.setStatus(ProductStatusEnum.Available);
            repository.save(product);
        }else{
            entity.setStatus(ProductStatusEnum.Available);
            entity.setProductName(product.getProductName());
            entity.setContent(product.getContent());
            entity.setFileId(product.getFileId());
            entity.setProductType(product.getProductType());
            entity.setSubProductType(product.getSubProductType());
            entity.setRemarks(product.getRemarks());
            repository.save(entity);
        }


        //用商品属性接收前端发送来的数据
        ResultJson<List<Product>> resultJson = ResultJson.success();
        return resultJson;
    }

    public ResultJson<?> addProductStandard(Product product) {
        Product p = repository.findByProductCode(product.getProductCode());

        if (product != null){
            ResultJson<Page<Product>> resultJson = ResultJson.failure(ResultCode.ISEXIT_RESURCE);
            return resultJson;
        }
        Product entity = new Product();
        p.setUnit(product.getUnit());
        repository.save(p);
        //用商品属性接收前端发送来的数据
        List<Spec> list = product.getProductSpecList();
        //创建一个商品属性实例 保存信息
        Spec s = new Spec();
        if (list != null){
            for (Spec a: list) {
                s.setSpecName(a.getSpecName());
                s.setSpecCode(a.getSpecCode());
            }
            SpecRepository.saveAll(list);

        }
        if(!CollectionUtils.isEmpty(product.getBrandList())){
            for(Brand bp:product.getBrandList()){
                if(StringUtils.isEmpty(bp.getBrandServiceCode())){
                    brandRepository.save(bp);
                }
                BrandProduct brandProduct = new BrandProduct();
                brandProduct.setProductCode(product.getProductCode());
                brandProduct.setProductName(product.getProductName());
                brandProduct.setBrandCode(bp.getBrandCode());
                brandProduct.setBrandName(bp.getBrandName());
                BrandProduct bpTem = brandProductRepository.findByProductCodeAndBrandCode(product.getProductCode(), bp.getBrandCode());
                if(bpTem == null){
                    brandProductRepository.save(brandProduct);
                }
            }
        }

        List<ProductFile> fileList = product.getProductFileList();
        if(!CollectionUtils.isEmpty(fileList)){
            for(ProductFile pf:fileList){
                pf.setProductCode(product.getProductCode());
            }
            productFileRepository.saveAll(fileList);
        }
        if(CollectionUtils.isEmpty(product.getProductVideoList())){
            productVideoRepository.saveAll(product.getProductVideoList());
        }

        ResultJson<List<Product>> resultJson = ResultJson.success();
        return resultJson;
    }

    public ResultJson<?> queryProductFiles(String productCode) {
        List<ProductFile> files = productFileRepository.findByProductCode(productCode);
        ResultJson<List<ProductFile>> resultJson = ResultJson.success();
        resultJson.setData(files);
        return resultJson;
    }

    public ResultJson<?> queryProductVideo(String productCode) {
        List<ProductVideo> files = productVideoRepository.findByProductCode(productCode);
        ResultJson<List<ProductVideo>> resultJson = ResultJson.success();
        resultJson.setData(files);
        return resultJson;
    }
}
